package blue.global.encrypt;

import java.security.Key;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;

import blue.global.util.NumberUtil;

/**
 * DESede 对称加密算法类
 * 
 * @author zhengj
 * @since 1.0
 * @date 2009-1-30
 */
public class DESedeUtil
{
	private static Cipher cipher;
	private static SecretKeyFactory factory;
	
	static
	{
		try
		{
			cipher = Cipher.getInstance("DESede");
			factory = SecretKeyFactory.getInstance("DESede");
		}
		catch (Exception e)
		{
			e.printStackTrace();
			throw new ExceptionInInitializerError(e);
		}
	}
	
	/**
	 * 根据一字符串产生 DESede 的密钥
	 * 
	 * @param key 字符串
	 * @return DESede 的密钥
	 */
	public static SecretKey generateKey(String key)
	{
		try
		{
			byte[] md = MessageDigestUtil.getMD5(key).getBytes("UTF-8");
			return factory.generateSecret(new DESedeKeySpec(md));
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 小数据量加密
	 * 
	 * @param key DESede 密钥
	 * @param data 明文
	 * @return 密文
	 */
	public static String encrypt(SecretKey key, String data)
	{
		String raw = null;
		try
		{
			cipher.init(Cipher.ENCRYPT_MODE, key);
			byte[] tmp = cipher.doFinal(data.getBytes("UTF-8"));
			raw = NumberUtil.toHexString(tmp);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return raw;
	}
	
	/**
	 * 小数据量解密
	 * 
	 * @param key DESede 密钥
	 * @param raw 密文
	 * @return 明文
	 */
	public static String decrypt(Key key, String raw)
	{
		String data = null;
		try
		{
			cipher.init(Cipher.DECRYPT_MODE, key);
			byte[] tmp = cipher.doFinal(NumberUtil.toBytes(raw));
			data = new String(tmp, "UTF-8");
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return data;
	}

	public static void main(String[] args) throws Exception
	{
		String str = "半糖主义111111";
		SecretKey key = generateKey("blue");
		String raw = encrypt(key, str);
		String data = decrypt(key, raw);
		
		System.out.println("原文：" + str);
		System.out.println("密钥：" + NumberUtil.toHexString(key.getEncoded()));
		System.out.println("密文：" + raw);
		System.out.println("原文：" + data);
	}
}
